﻿<?php
/**
 * 请求分发器类定义文件
 *
 * @author Chairou
 * @package base
 */
defined('IN_WEB') or die('Include Error!');

include(PATH_LIB . "mobile/class.adapter.php");

/**
 * 请求分发器类
 *
 */
class Distru{
	
	/**
	 * 当前请求控制器类名
	 *
	 * @var string
	 */
	public static $class;

	/**
	 * 当前请求控制器类方法名
	 *
	 * @var string
	 */
	public static $method;

	/**
	 * 旧版接口分发请求
	 *
	 * @return object 控制器对象
	 */
	private static function _dispatch_v5(){
		include(PATH_API . 'v5/Server.php');
		if(! @include( PATH_API .'v5/'.self::$class.'.php')) die('3');

		class_exists(self::$class) or die('4');
		$obj = new self::$class;
		method_exists($obj, self::$method) or die('5');
		$method = self::$method;
		return $obj->$method($_REQUEST);
	}

	/**
	 * 新版接口分发请求
	 *
	 * @return object 控制器对象
	 */
	private static function _dispatch_v8(){
		//先要验证输入合法性
		if (condition) {
			AAAA();
		}
		
		//验证配置
		if(empty($_REQUEST['api']) || !in_array(oo::$config['api'][$_REQUEST['api']][1], (array)oo::$config['needstatsid'])){
			die('4');
		}
		//控制器类名、文件名定义
		$className		= self::$class . 'Controller';
		$classFile		= PATH_API .'v8/'. oo::$config['clientApiDir'][$_REQUEST['api']] .'/'. self::$class .'.php';
		$baseClassName	= self::$class . 'Base';
		$baseClassFile	= PATH_API .'v8/common/'. $baseClassName .'.php';
		//验证文件是否存在
		if(!file_exists($classFile) || !file_exists($baseClassFile)){
			return self::_dispatch_v5();
		}
		//引入文件
		@include(PATH_LIB . "mobile/class.controller.php");
		@include($baseClassFile);
		//验证基类是否存在
		if(!class_exists($baseClassName)){
			return self::_dispatch_v5();
		}
		//验证方法是否存在(故意验证父类，强迫每个方法在父类中实现)
		$classRel = new ReflectionClass($baseClassName);
		if(!$classRel->hasMethod(self::$method)){
			return self::_dispatch_v5();
		}
		//验证方法是否公开
		$methodRel = $classRel->getMethod(self::$method);
		if(!$methodRel->isPublic()){
			//return self::_dispatch_v5();
			die('x');
		}
		//引入子类文件
		@include($classFile);
		
		//验证子类是否存在
		if(!class_exists($className)){
			return self::_dispatch_v5();
		}
		//调用方法，用controller封装了一层，其实我倒是觉得没必要
		$controller = new $className;
		return $controller->__call(self::$method, null);
	}

	/**
	 * 分发请求
	 *
	 */
	public static function dispatch(){
		//input
		if(BteaAdapter::enabled()){
			$adapter = new BteaAdapter;
		}elseif(ProtobufAdapter::enabled()){
			$adapter = new ProtobufAdapter;
		}else{
			$adapter = new JsonAdapter;
		}
		$_REQUEST = $adapter->in();

		//dispatch
		if(empty($_REQUEST['method'])){
			die('3');
		}
		//分割类与方法
		list(self::$class, self::$method) = explode('.', $_REQUEST['method']);
		if(empty(self::$class) || empty(self::$method)){
			die('3');
		}
		
		//首字母大写，这种无聊的玩意，浪费服务器资源
		self::$class = ucfirst(self::$class); 
		
		// 区分采用V8还是V5接口，V8接口上更简洁强壮
		if(isset($_SERVER['HTTP_API_V8']) && isset(oo::$config['clientApiDir'][$_REQUEST['api']])){
			$result = self::_dispatch_v8();
		}

		//output ， 主要用json封装
		$output = $adapter->out($result);
		if(!empty($callback)){
			header('Content-Type: text/javascript');
			die($callback .'('. $output .');');
		}else{
			die($output);
		}
	}
}